/**
 推荐的修复方法是将该函数移到effect中。这样就很容易看到你effect使用到的props和state，并确保它们都被声明了
 The recommended fix is to move that function inside of your effect. That makes it easy to see which props or state your effect uses, and to ensure they’re all declared:
*/
import React, {useCallback, useEffect, useState} from 'react';

interface Props {
  someProp: any;
}

/** 1)推荐将函数写在useEffect里,这样你就不会忘记声明其使用的依赖*/
function X({someProp}: Props) {

  /** 不推荐下面这种写法↓*/
  /*
    It’s difficult to remember which props or state are used by functions outside of the effect.
  */
  // function doSomething() {
  //   console.log('someProp:',someProp);
  // }
  //
  // useEffect(() => {
  //   doSomething();
  // }, [someProp]); // 🔴 This is not safe (it calls `doSomething` which uses `someProp`)

  /** This is why usually you’ll want to declare functions needed by an effect inside of it. Then it’s easy to see what values from the component scope that effect depends on:*/
  useEffect(() => {
    function doSomething() {
      console.log(someProp);
    }

    doSomething();
  }, [someProp]); // ✅ OK (our effect only uses `someProp`)

  return (
    <div>
      {someProp}
    </div>
  )
}

export default function(){
  const [state, setState] = useState(0);
  const changeProps = useCallback(() => {
    setState(x => x + 1);
  }, []);

  return (
    <>
      <X someProp={state}/>
      <button onClick={changeProps}>button</button>
    </>
  );
}



/* bug例子示意↓
function ProductPage({ productId }) {
  const [product, setProduct] = useState(null);

  async function fetchProduct() {
    const response = await fetch('http://myapi/product/' + productId); // Uses productId prop
    const json = await response.json();
    setProduct(json);
  }

  useEffect(() => {
    fetchProduct();
  }, []); // 🔴 Invalid because `fetchProduct` uses `productId`
  // ...
}
*/


/** 2) 你如果你处于某种原由不能写在useEffect里,你可以尝试:
 * + 将函数移动到组件外
 * + 如果是纯函数,无需useEffect包裹
 * + ↓↓*/

/*
function ProductPage({ productId }) {
  // ✅ Wrap with useCallback to avoid change on every render
  const fetchProduct = useCallback(() => {
    // ... Does something with productId ...
  }, [productId]); // ✅ All useCallback dependencies are specified

  return <ProductDetails fetchProduct={fetchProduct} />;
}

function ProductDetails({ fetchProduct }) {
  useEffect(() => {
    fetchProduct();
  }, [fetchProduct]); // ✅ All useEffect dependencies are specified
  // ...
}
*/
